package net.cocotea.sqltoy.lambda.util;

import net.cocotea.sqltoy.lambda.func.SFunction;
import org.sagacity.sqltoy.config.annotation.Column;

import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 列工具类
 * 
 * @author CoCoTea
 * @since 0.0.3
 */
public class ColUtils {

    /**
     * 获取字段名
     * 
     * @param sFunc 函数
     * @return 字段名
     */
    private static <T> String getFiled(SFunction<T, ?> sFunc) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException, ClassNotFoundException {
        Class<?> funcClass = sFunc.getClass();

        Method method = funcClass.getDeclaredMethod("writeReplace");
        method.setAccessible(true);

        SerializedLambda serializedLambda = (SerializedLambda) method.invoke(sFunc);
        String implMethodName = serializedLambda.getImplMethodName();

        method.setAccessible(false);

        if (implMethodName.startsWith("get")) {
            // 拼接字段名
            String filedPrefix = implMethodName.substring(3, 4).toLowerCase();
            String filedSuffix = implMethodName.substring(4);
            String filedName = (filedPrefix + filedSuffix);

            // 获取泛型Class
            Class<?> TClass = Class.forName(serializedLambda.getImplClass().replace("/", "."));

            // 读取字段
            Field declaredField = TClass.getDeclaredField(filedName);
            Column column = declaredField.getAnnotation(Column.class);
            return column.name();
        }

        return null;
    }

    /**
     * 获取字段名
     * 
     * @param sFunc 函数
     * @return 字段名
     */
    public static <T> String filedName(SFunction<T, ?> sFunc) {
        try {
            return getFiled(sFunc);
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException | NoSuchFieldException |
                 ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

}
